package com.jianbing.controller;

import java.util.Date;
import java.util.UUID;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.jianbing.dao.MongoDBDao;
import com.jianbing.entity.AccessLog;
import com.jianbing.entity.AccessToken;
import com.jianbing.entity.Customer;
import com.jianbing.entity.CustomerProduct;
import com.jianbing.entity.Goods;
import com.jianbing.entity.Result;
import com.jianbing.util.Constants;
import com.jianbing.util.IPUtil;
import com.jianbing.util.SignUtil;
import com.jianbing.util.StringUtils;
import com.jianbing.util.TableUtil;
import com.mongodb.BasicDBObject;

import net.sf.json.JSONObject;

/**
 * 
 * @author cwl
 * @date 2017年5月11日
 *
 */
@Controller
@RequestMapping(value = "/access")
public class AccessController {
	Logger logger = Logger.getLogger(AccessController.class);

	@Value("#{propertiesReader['token_active_time']}")
	private int token_active_time;

	@Value("#{propertiesReader['accessTime']}")
	private int accessTime;

	/**
	 * 
	 * 获取访问令牌
	 * 
	 * @author cwl
	 * @date 2017年5月11日
	 *
	 * @param response
	 * @param user
	 * @return
	 */
	@RequestMapping(value = "/getToken", method = RequestMethod.POST)
	@ResponseBody
	public Result getToken(HttpServletRequest request, HttpServletResponse response, @RequestBody String body) {
		logger.info("获取token---" + body);
		Result result = new Result();
		String accessIp = IPUtil.getIpAddr(request);
		ModelMap model = new ModelMap();
		Date accessDate = new Date();
		try {
			JSONObject json = JSONObject.fromObject(body);
			JSONObject jsonParams = json.getJSONObject("params");
			if (StringUtils.isEmpty(jsonParams.getString("appKey"))
					|| StringUtils.isEmpty(jsonParams.getString("timestamp"))
					|| StringUtils.isEmpty(json.getString("sign"))) {
				result.setCode(101);
				result.setMsg("参数错误");
				return result;
			}
			if ((jsonParams.getLong("timestamp") + accessTime * 1000) < accessDate.getTime()) {
				result.setCode(102);
				result.setMsg("时间戳超时");
				return result;
			}
			BasicDBObject queryObject = new BasicDBObject();
			queryObject.append("appKey", jsonParams.getString("appKey"));
			Customer customer = MongoDBDao.findOne(TableUtil.customer, Customer.class, queryObject);
			if (customer == null) {
				result.setCode(103);
				result.setMsg("无效的appKey");
				return result;
			}
			if (!SignUtil.checkSign(json.getString("sign"), jsonParams, customer.getAppSecret())) {
				result.setCode(104);
				result.setMsg("签名错误");
				return result;
			}

			// 用UUID生成token
			UUID uuId = UUID.randomUUID();
			String token = uuId.toString().replaceAll("-", "");// 就生成token了吗

			AccessToken accessToken = MongoDBDao.findOne(TableUtil.accessToken, AccessToken.class, queryObject);
			if (accessToken == null) {
				accessToken = new AccessToken();
				accessToken.setAppKey(jsonParams.getString("appKey"));
				accessToken.setCreateTime(accessDate.getTime());
				accessToken.setToken(token);
				accessToken.setActiveTime(accessToken.getCreateTime() + token_active_time * 60 * 60 * 1000);
				accessToken.setAccessIp(accessIp);
				MongoDBDao.insert(TableUtil.accessToken, accessToken);
			} else {
				accessToken.setCreateTime(accessDate.getTime());
				accessToken.setToken(token);
				accessToken.setActiveTime(accessToken.getCreateTime() + token_active_time * 60 * 60 * 1000);
				accessToken.setAccessIp(accessIp);
				MongoDBDao.update(TableUtil.accessToken, accessToken, queryObject);
			}

			String log = "ip=" + accessIp + " appKey=" + jsonParams.getString("appKey") + ",获取Token="
					+ accessToken.getToken();
			AccessLog accessLog = new AccessLog();
			accessLog.setAccessDate(accessDate);
			accessLog.setAccessIp(accessIp);
			accessLog.setAppkey(jsonParams.getString("appKey"));
			accessLog.setMsg(log);
			MongoDBDao.insert(TableUtil.accessLog, accessLog);
			logger.info(log);
			model.addAttribute("token", accessToken.getToken());
			result.setData(model);
		} catch (Exception e) {
			logger.error(e.getMessage(), e);
			result.setCode(-1);
			result.setMsg("系统异常");
			return result;
		}
		return result;

	}

	/**
	 * 
	 * 签名合法性校验
	 * 
	 * @author cwl
	 * @date 2017年5月11日
	 *
	 * @param request
	 * @param response
	 * @return
	 */
	@SuppressWarnings("static-access")
	@RequestMapping(value = "/signValidityCheck", method = RequestMethod.POST)
	@ResponseBody
	public Result signValidityCheck(HttpServletRequest request, HttpServletResponse response,
			@RequestBody String body) {
		Result result = new Result();
		try {
			Date now = new Date();
			logger.info("签名校验" + body);
			JSONObject json = JSONObject.fromObject(body);
			if (StringUtils.isEmpty(json.getString("sign")) || StringUtils.isEmpty(json.getString("param"))
					|| json.get("type") == null) {
				result.setCode(-1);
				result.setMsg("参数错误");
				return result;
			}
			JSONObject jsonParam = JSONObject.fromObject(json.get("param"));
			MongoDBDao dbDao = new MongoDBDao();
			BasicDBObject queryObject = new BasicDBObject();
			queryObject.append("appKey", jsonParam.get("appKey"));
			Customer customer = dbDao.findOne(TableUtil.customer, Customer.class, queryObject);
			if (customer == null) {
				result.setCode(-1);
				result.setMsg("客户不存在");
				return result;
			}

			AccessToken accessToken = MongoDBDao.findOne(TableUtil.accessToken, AccessToken.class, queryObject);
			if (accessToken == null || accessToken.getActiveTime() < now.getTime()) {
				result.setCode(-1);
				result.setMsg("token已失效");
				return result;
			}

			BasicDBObject goodsQueryObject = new BasicDBObject();
			goodsQueryObject.append("goodsType", json.getString("type"));
			Goods goods = MongoDBDao.findOne(TableUtil.goods, Goods.class, goodsQueryObject);
			if (goods == null) {
				result.setCode(-1);
				result.setMsg("sorry,暂不提供此服务");
				return result;
			}

			queryObject.append("goodsSn", goods.getGoodsSn());
			CustomerProduct customerProduct = MongoDBDao.findOne(TableUtil.customer_product, CustomerProduct.class,
					queryObject);
			if (customerProduct == null) {
				result.setCode(-1);
				result.setMsg("sorry,您暂未开通此服务");
				return result;
			}

			if ((jsonParam.getLong("timestamp") + accessTime * 1000) < now.getTime()) {
				result.setCode(-1);
				result.setMsg("时间戳超时");
				return result;
			}
			if (!SignUtil.checkSign(json.getString("sign"), jsonParam, customer.getAppSecret())) {
				result.setCode(-1);
				result.setMsg("签名错误");
				return result;
			}
		} catch (Exception e) {
			logger.error(e.getMessage(), e);
			result.setCode(-1);
			result.setMsg("系统异常");
			return result;
		}
		result.setMsg("success");
		return result;
	}
}
